﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Lex.Db;
using Tomato.Libraries.Databases.Models;
using Tomato.Libraries.Patterns;

namespace Tomato.Libraries.Databases
{
    /// <summary>
    /// Interface to work with Lex Db.
    /// </summary>
    public class ExpenseDiaryDatabase : DbInstance, IDisposable
    {

        public ExpenseDiaryDatabase( string path = "expensediary.db" )
            : base( path )
        {

            Map<Account>( )
                .Automap<Guid>( a => a.Id, true )
                .WithIndex<string>( "Name", a => a.Name )
                .WithIndex<Guid>( "AccountCategoryId", a => a.AccountCategoryId )
                .WithIndex<Guid>( "CurrencyId", a => a.CurrencyId )
                .WithIndex<Guid, Guid>( "AccountCategoryId_CurrencyId", a => a.AccountCategoryId, a => a.CurrencyId );

            Map<AccountCategory>( )
                .Automap<Guid>( ac => ac.Id )
                .WithIndex<string>( "Name", ac => ac.Name );

            Map<Currency>( )
                .Automap<Guid>( c => c.Id, true )
                .WithIndex<string>( "Code", c => c.Code )
                .WithIndex<string>( "Name", c => c.Name );

            Map<Position>( )
                .Automap<Guid>( p => p.Id, true )
                .WithIndex<Guid>( "AccountId", p => p.AccountId )
                .WithIndex<Guid, DateTime>( "AccountId_Month", p => p.Id, p => p.Month );

            Map<Transaction>( )
                .Automap<Guid>( t => t.Id, true )
                .WithIndex<Guid>( "AccountId", t => t.AccountId )
                .WithIndex<Guid>( "ReferenceAccountId", t => t.ReferenceAccountId )
                .WithIndex<DateTime>( "Date", t => t.Date )
                .WithIndex<Guid, DateTime>( "AccountIdAndDate", t => t.AccountId, t => t.Date );

            Map<TransactionCategory>( )
                .Automap<Guid>( tc => tc.Id, true )
                .WithIndex<string>( "Name", tc => tc.Name )
                .WithIndex<Guid>( "TransactionCategoryGroupId", tc => tc.TransactionCategoryGroupId );

            Map<TransactionCategoryGroup>( )
                .Automap<Guid>( tcg => tcg.Id, true )
                .WithIndex<string>( "Name", tcg => tcg.Name );

            Map<Event>( )
                .Automap<Guid>( e => e.Id, true )
                .WithIndex<Guid>( "ProviderId", e => e.ProviderId )
                .WithIndex<string>( "ProviderName", e => e.ProviderName );

            Initialize( );
        }

        private DbTable<Account> _accounts;
        public DbTable<Account> Accounts
        {
            get
            {
                return _accounts ?? ( _accounts = Table<Account>( ) );
            }
        }

        private DbTable<AccountCategory> _accountCategories;
        public DbTable<AccountCategory> AccountCategories
        {
            get
            {
                return _accountCategories ?? ( _accountCategories = Table<AccountCategory>( ) );
            }
        }

        private DbTable<Currency> _currencies;
        public DbTable<Currency> Currencies
        {
            get
            {
                return _currencies ?? ( _currencies = Table<Currency>( ) );
            }
        }

        private DbTable<Position> _positions;
        public DbTable<Position> Positions
        {
            get
            {
                return _positions ?? ( _positions = Table<Position>( ) );
            }
        }

        private DbTable<Transaction> _transactions;
        public DbTable<Transaction> Transactions
        {
            get
            {
                return _transactions ?? ( _transactions = Table<Transaction>( ) );
            }
        }

        private DbTable<TransactionCategory> _transactionCategories;
        public DbTable<TransactionCategory> TransactionCategories
        {
            get
            {
                return _transactionCategories ?? ( _transactionCategories = Table<TransactionCategory>( ) );
            }
        }

        private DbTable<TransactionCategoryGroup> _transactionCategoryGroups;
        public DbTable<TransactionCategoryGroup> TransactionCategoryGroups
        {
            get
            {
                return _transactionCategoryGroups ?? ( _transactionCategoryGroups = Table<TransactionCategoryGroup>( ) );
            }
        }

        private DbTable<Event> _events;
        public DbTable<Event> Events
        {
            get
            {
                return _events ?? ( _events = Table<Event>( ) );
            }
        }

        void IDisposable.Dispose( )
        {
        }

    }
}
